package seatiger.tomcat.catalina.core;

import seatiger.tomcat.catalina.*;
import seatiger.tomcat.catalina.util.LifecycleSupport;
import seatiger.tomcat.util.StringManager;

import java.util.ArrayList;
import java.util.List;

/**
 * 服务组件的标准实现
 */
public class StandardService implements Lifecycle, Service {

    private static final String info =
            "seatiger.tomcat.catalina.core.StandardService/1.0";

    private LifecycleSupport lifecycle = new LifecycleSupport(this);

    private Container container;

    private Server server;

    private String name;

    private List<Connector> connectors = new ArrayList<>(2);

    private static final StringManager sm = StringManager.getManager(Constants.PACKAGE_CORE);

    /**
     * 是否已经初始化完成
     */
    private volatile boolean initialized = false;

    /**
     * 组件是否已经启动
     */
    private boolean started = false;

    @Override
    public void addLifecycleListener(LifecycleListener listener) {
        lifecycle.addLifecycleListener(listener);
    }

    @Override
    public List<LifecycleListener> findLifecycleListeners() {
        return lifecycle.findLifecycleListeners();
    }

    @Override
    public void removeLifecycleListener(LifecycleListener listener) {
        lifecycle.removeLifecycleListener(listener);
    }

    @Override
    public void start() throws LifecycleException {
        if (started){
            throw new LifecycleException(sm.getString("standardService.start.started"));
        }
        lifecycle.fireLifecycleEvent(BEFORE_START_EVENT,null);
        System.out.println("standardService.start.name" + this.name);
        lifecycle.fireLifecycleEvent(START_EVENT, null);
        lifecycle.fireLifecycleEvent(START_EVENT,null);
        started = true;
        //启动容器
        startComponents(container);
        synchronized (connectors){
            startComponents(connectors.toArray());
        }
        lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null);
    }

    @Override
    public Container getContainer() {
        return this.container;
    }

    @Override
    public void setContainer(Container container) {
        Container oldContainer = this.container;
        if (oldContainer != null && oldContainer instanceof Engine){
            ((Engine) oldContainer).setService(null);
        }
        this.container = container;
        if (this.container != null && this.container instanceof Engine){
            ((Engine) container).setService(this);
        }
        //如果整个服务已经启动过了，那么新增的容器需要单独启动
        if (started && this.container != null){
            try {
                startComponents(this.container);
            }catch (LifecycleException e){
            }
        }

        //每个连接器关联一个容器
        synchronized (connectors){
            connectors.forEach(connector -> connector.setContainer(this.container));
        }
    }

    @Override
    public String getInfo() {
        return info;
    }

    @Override
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public void addConnector(Connector connector) {
        synchronized (connectors){
            connector.setContainer(this.container);
            connector.setService(this);
            connectors.add(connector);
            //如果服务组件已经初始化了，需要单独初始化
            if (initialized){
                try {
                    connector.initialize();
                } catch (LifecycleException e) {
                    e.printStackTrace(System.err);
                }
            }

            if (started){
                try {
                    startComponents(connector);
                } catch (LifecycleException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public List<Connector> findConnectors() {
        return this.connectors;
    }

    @Override
    public void initialize() throws LifecycleException {
        if (initialized){
            throw new LifecycleException (sm.getString("standardService.initialize.initialized"));
        }
        initialized = true;
        //将连接器启动
        synchronized (connectors){
            for (Connector connector : connectors){
                connector.initialize();
            }
        }
    }

    @Override
    public Server getServer() {
        return this.server;
    }

    @Override
    public void setServer(Server server) {
        this.server = server;
    }

    @Override
    public void stop() throws LifecycleException {
        if (!started){
            throw new LifecycleException(sm.getString("standardService.stop.notStarted"));
        }
        lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
        lifecycle.fireLifecycleEvent(STOP_EVENT, null);
        started = false;
        stopComponents(connectors.toArray());
        stopComponents(container);
    }
}
